package setting

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

var Conf = new(AppConfig)

type AppConfig struct {
	Name      string `mapstructure:"name"`
	Mode      string `mapstructure:"mode"`
	Host      string `mapstructure:"host"`
	StartTime string `mapstructure:"start_time"`
	MachineID int64  `mapstructure:"machine_id"`
	Port      int    `mapstructure:"port"`

	*LogConfig   `mapstructure:"log"`
	*MySQLConfig `mapstructure:"mysql"`
	*RedisConfig `mapstructure:"redis"`
}
type LogConfig struct {
	Level      string `mapstructure:"level"`
	Filename   string `mapstructure:"filename"`
	MaxSize    int    `mapstructure:"max_size"`
	MaxAge     int    `mapstructure:"max_age"`
	MaxBackups int    `mapstructure:"max_backups"`
}
type MySQLConfig struct {
	Host        string `mapstructure:"host"`
	User        string `mapstructure:"user"`
	Password    string `mapstructure:"password"`
	Dbname      string `mapstructure:"dbname"`
	Port        int    `mapstructure:"port"`
	MaxOpenConn int    `mapstructure:"max_open_conn"`
	MaxIdleConn int    `mapstructure:"max_idle_conn"`
}
type RedisConfig struct {
	Host     string `mapstructure:"host"`
	Password string `mapstructure:"password"`
	Port     int    `mapstructure:"port"`
	Db       int    `mapstructure:"db"`
	PoolSize int    `mapstructure:"pool_size"`
}

// 初始化配置文件1eb664fa9b91
func Init(filePath string) (err error) {
	// 指定配置文件路径
	viper.SetConfigFile(filePath)
	//// 指定配置文件名称(无扩展名)
	//viper.SetConfigName("config")
	//// 如果配置文件名称中没有扩展名,则需要配置此项
	//viper.SetConfigType("yaml")
	// 查找并读取配置文件
	if err = viper.ReadInConfig(); err != nil {
		fmt.Printf("读取配置文件失败:%v\n", err)
		return err
	}
	// 把读取到的配置信息反序列化到 Conf 变量中
	if err = viper.Unmarshal(Conf); err != nil {
		fmt.Printf("反序列化配置文件失败:%v\n", err)
		return err
	}
	// 监听并重新读取配置文件
	viper.WatchConfig()
	viper.OnConfigChange(func(e fsnotify.Event) {
		// 配置文件变更后会调用的回调函数
		fmt.Println("重新加载配置文件:", e.Name)
		// 把读取到的配置信息反序列化到 Conf 变量中
		if err = viper.Unmarshal(Conf); err != nil {
			fmt.Printf("反序列化配置文件失败:%v\n", err)
		}
	})
	return err
}
